# ListIndicator - Displays currently selected item and length of the list
# Copyright (C) 2007 Lauri Taimila
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

__licence__ = "GPLv2"
__copyright__ = "2007, Lauri Taimila"
__author__ = "Lauri Taimila <lauri@taimila.com>"

import clutter
from frontend.gui.widgets.arrow_texture import ArrowTexture

class ListIndicator(clutter.Group):
    """
    ListIndicator displays 'current / maximum' value label and arrows.
    """
    
    # Direction
    # HORIZONTAL layout: ARROW_LEFT current / maximum ARROW_RIGHT
    # VERITCAL layout:   current / maximum ARROW_UP ARROW_DOWN
    HORIZONTAL = 0
    VERTICAL = 1
    
    def __init__(self, width, height, theme, direction):
        """
        Initialize actor.
        @param width: Width of the actor
        @param height: Height of the actor
        @param theme: Theme object
        @param direction: Direction (constant of this class)
        """
        clutter.Group.__init__(self)
        self.theme = theme
        self.fg = theme.getColor("arrow_foreground")
        self.bg = theme.getColor("arrow_background")
        self.width = width
        self.height = height
        self.direction = direction
        self.delimiter = " / "
        self.current = 1
        self.maximum = 1
        
        # Use transparent rectangle to set size of the scroll area
        # FIXME: Is there another way? This seems a bit hackish solution.
        rect = clutter.Rectangle()
        rect.set_size(width, height)
        rect.set_color(clutter.Color(0,0,0,0))
        rect.show()
        self.add(rect)
        
        # Create and initialize text label
        self.text = clutter.Label()
        self.text.set_color(theme.getColor("text"))
        self.text.set_font_name(theme.getFont() + " 28px")
        self.text.set_text(str(self.maximum) + self.delimiter + str(self.maximum))
        self.text.set_line_wrap(False)
        
        # Set text into the middle if horizontal. Next to arrows if vertical
        if direction == ListIndicator.VERTICAL:
            self.text.set_position(self.width - (self.text.get_width() + height * 2 + (height / 2)), 
                                     (height - self.text.get_height()) / 2)
        else:
            self.text.set_position((width - self.text.get_width()) / 2, 
                                     int((height - self.text.get_height()) / 2))
        self.text.show()
        self.add(self.text)
        
        # Create arrows
        if direction == ListIndicator.VERTICAL:
            self.arrow1 = ArrowTexture(height, self.fg, self.bg, ArrowTexture.UP)
            self.arrow2 = ArrowTexture(height, self.fg, self.bg, ArrowTexture.DOWN)
            self.arrow1.set_position(self.width - (height * 2 + int(height / 4)), 0)
            self.arrow2.set_position(self.width - height, 0) 
        elif direction == ListIndicator.HORIZONTAL:
            self.arrow1 = ArrowTexture(height, self.fg, self.bg, ArrowTexture.LEFT)
            self.arrow2 = ArrowTexture(height, self.fg, self.bg, ArrowTexture.RIGHT)
            self.arrow1.set_position(0,0)
            self.arrow2.set_position(self.width - height, 0)
            
        self.arrow1.show()
        self.arrow2.show()
        self.add(self.arrow1)
        self.add(self.arrow2)
        
    def set_current(self, value):
        """
        Set current value
        @param number: Current value (between 1 - maximum)
        """
        if value > 0 and value <= self.maximum:
            self.current = value
            self._update_widget_actors()
            
            # Lower arrow's opacity if limit value is reached
            if self.current == 1:
                self.arrow1.set_opacity(128)
                self.arrow2.set_opacity(255)
            elif self.current == self.maximum:
                self.arrow1.set_opacity(255)
                self.arrow2.set_opacity(128)
            else:
                self.arrow1.set_opacity(255)
                self.arrow2.set_opacity(255)
    
    def get_current(self):
        """
        Get current value
        @return Current value (integer)
        """
        return self.current
        
    def set_maximum(self, value):
        """
        Set maximum value of the indicator
        @param number: Set maximum value
        """
        self.maximum = value
        self._update_widget_actors()
    
    def get_maximum(self):
        """
        Get maximum value.
        @return Max value (integer)
        """
        return self.maximum
            
    def set_delimiter(self, delimiter):
        """
        Set delimiter text that is displayed between current and maximum value.
        Default delimiter text is ' / ' spaces included.
        @param delimiter: delimiter text
        """
        self.delimiter = delimiter
        self._update_widget_actors()  
    
    def set_font_name(self, text):
        """
        Set font name for label.
        @param text: Clutter style font name. Example: "Sans 24"
        """
        self.text.set_font_name(text)
        self._update_widget_actors()
        
#    def set_foreground_color(self, color):
#        """
#        Set foreground color of the widget.
#        @param color: New color for foreground (Clutter.Color)
#        """
#        self.fg = color
#        self.text.set_color(color)
#        self.remove(self.arrow1)
#        self.remove(self.arrow2)
#        if self.direction == ListIndicator.VERTICAL:
#            self.arrow1 = ArrowTexture(self.height, self.fg, self.bg, ArrowTexture.UP)
#            self.arrow2 = ArrowTexture(self.height, self.fg, self.bg, ArrowTexture.DOWN)
#        elif self.direction == ListIndicator.HORIZONTAL:
#            self.arrow1 = ArrowTexture(self.height, self.fg, self.bg, ArrowTexture.LEFT)
#            self.arrow2 = ArrowTexture(self.height, self.fg, self.bg, ArrowTexture.RIGHT)
#        self.arrow1.show()
#        self.arrow2.show()
#        self.add(self.arrow1)
#        self.add(self.arrow2)
#        self.__update_widget_actors()
#        
#    def set_background_color(self, color):
#        """
#        Set background color of the widget.
#        @param color: New color for background (Clutter.Color)
#        """
#        self.bg = color
#        self.remove(self.arrow1)
#        self.remove(self.arrow2)
#        if self.direction == ListIndicator.VERTICAL:
#            self.arrow1 = ArrowTexture(self.height, self.fg, self.bg, ArrowTexture.UP)
#            self.arrow2 = ArrowTexture(self.height, self.fg, self.bg, ArrowTexture.DOWN)
#        elif self.direction == ListIndicator.HORIZONTAL:
#            self.arrow1 = ArrowTexture(self.height, self.fg, self.bg, ArrowTexture.LEFT)
#            self.arrow2 = ArrowTexture(self.height, self.fg, self.bg, ArrowTexture.RIGHT)
#        self.arrow1.show()
#        self.arrow2.show()
#        self.add(self.arrow1)
#        self.add(self.arrow2)
#        self.__update_widget_actors()
    
    def show_position(self):
        """
        Show position text that indicates the current position of the content.
        """
        self.text.show()
        
    def hide_position(self):
        """
        Hide position text that indicates the current position of the content.
        If this is called then indicator shows only arrows.
        """
        self.text.hide()
    
    def _update_widget_actors(self):
        """
        Update widget actors.
        """
        # Update text
        self.text.set_text(str(self.current) + self.delimiter + str(self.maximum))
        
        # Update text position
        if self.direction == ListIndicator.VERTICAL:
            self.text.set_position(self.width - (self.text.get_width() + self.height * 2 + int(self.height / 2)), 
                                   (self.height - self.text.get_height()) / 2)
        else:
            self.text.set_position((self.width - self.text.get_width()) / 2, 
                                   int((self.height - self.text.get_height()) / 2))
            